package com.dzt.cloudreader.network;

import android.content.Context;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;

import com.google.gson.FieldNamingPolicy;
import com.google.gson.FieldNamingStrategy;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;

import java.io.IOException;
import java.lang.reflect.Field;
import java.security.SecureRandom;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.util.concurrent.TimeUnit;

import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSession;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;

import okhttp3.Interceptor;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
import okhttp3.logging.HttpLoggingInterceptor;
import retrofit2.Retrofit;
import retrofit2.adapter.rxjava.RxJavaCallAdapterFactory;
import retrofit2.converter.gson.GsonConverterFactory;

/**
 * Created by M02323 on 2017/12/6.
 */

public class RetrofitHelper {
	//gankio服务器地址
	public static final String API_GANKIO = "http://gank.io/api/";
	//豆瓣
	private final static String API_DOUBAN = "https://api.douban.com/";
	//轮播图
	private final static String API_TING = "https://tingapi.ting.baidu.com/v1/restserver/";

	//GsonConverterFactory factory = GsonConverterFactory.create(new GsonBuilder().create());
	private static Context context;
	private Object gankHttps;
	private Object doubanHttps;
	private Object dongtingHttps;
	private Gson gson;
	private boolean debug = true;

	private static class SingletonHolder {
		static RetrofitHelper sInstance = new RetrofitHelper();
	}

	public static RetrofitHelper getInstance() {
		return SingletonHolder.sInstance;
	}

	private RetrofitHelper() {
	}

	public boolean isDebug() {
		return debug;
	}

	public void setDebug(boolean debug) {
		this.debug = debug;
	}

	public static void init(Context ctx) {
		context = ctx;
	}

	public <T> T getGankIOServer(Class<T> a) {
		if (gankHttps == null) {
			synchronized (RetrofitHelper.class) {
				if (gankHttps == null) {
					gankHttps = getBuilder(API_GANKIO).build().create(a);
				}
			}
		}
		return (T) gankHttps;
	}

	public <T> T getDouBanServer(Class<T> a) {
		if (doubanHttps == null) {
			synchronized (RetrofitHelper.class) {
				if (doubanHttps == null) {
					doubanHttps = getBuilder(API_DOUBAN).build().create(a);
				}
			}
		}
		return (T) doubanHttps;
	}

	public <T> T getTingServer(Class<T> a) {
		if (dongtingHttps == null) {
			synchronized (RetrofitHelper.class) {
				if (dongtingHttps == null) {
					dongtingHttps = getBuilder(API_TING).build().create(a);
				}
			}
		}
		return (T) dongtingHttps;
	}

	private Retrofit.Builder getBuilder(String apiUrl) {
		Retrofit.Builder builder = new Retrofit.Builder();
		builder.client(getOkClient());
		builder.baseUrl(apiUrl);//设置远程地址
		//builder.addConverterFactory(GsonConverterFactory.create(new GsonBuilder().create()));
		builder.addConverterFactory(new NullOnEmptyConverterFactory());
		builder.addConverterFactory(GsonConverterFactory.create(getGson()));
		builder.addCallAdapterFactory(RxJavaCallAdapterFactory.create());
		return builder;
	}

	private Gson getGson() {
		if (gson == null) {
			GsonBuilder builder = new GsonBuilder();
			builder.setLenient();
			builder.setFieldNamingStrategy(new AnnotateNaming());
			builder.serializeNulls();
			gson = builder.create();
		}
		return gson;
	}

	private static class AnnotateNaming implements FieldNamingStrategy {
		@Override
		public String translateName(Field field) {
			ParamNames a = field.getAnnotation(ParamNames.class);
			return a != null ? a.value() : FieldNamingPolicy.IDENTITY.translateName(field);
		}
	}

	public OkHttpClient getOkClient() {
		return getUnsafeOkHttpClient();
	}

	public OkHttpClient getUnsafeOkHttpClient() {
		try {
			final TrustManager[] trustAllCerts = new TrustManager[]{new X509TrustManager() {
				@Override
				public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {
				}

				@Override
				public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {
				}

				@Override
				public X509Certificate[] getAcceptedIssuers() {
					return new X509Certificate[]{};
				}
			}};
			// Install the all-trusting trust manager
			SSLContext sslContext = SSLContext.getInstance("TLS");
			sslContext.init(null, trustAllCerts, new SecureRandom());
			// Create an ssl socket factory with our all-trusting manager
			SSLSocketFactory sslSocketFactory = sslContext.getSocketFactory();
			OkHttpClient.Builder okBuilder = new OkHttpClient.Builder();
			okBuilder.readTimeout(20, TimeUnit.SECONDS);
			okBuilder.connectTimeout(10, TimeUnit.SECONDS);
			okBuilder.writeTimeout(20, TimeUnit.SECONDS);
			okBuilder.addInterceptor(new HttpHeadInterceptor());
			okBuilder.addInterceptor(getInterceptor());
			okBuilder.sslSocketFactory(sslSocketFactory);
			okBuilder.hostnameVerifier(new HostnameVerifier() {
				@Override
				public boolean verify(String hostname, SSLSession session) {
//                    Log.d("HttpUtils", "==come");
					return true;
				}
			});

			return okBuilder.build();
		} catch (Exception e) {
			throw new RuntimeException(e);
		}
	}

	class HttpHeadInterceptor implements Interceptor {
		@Override
		public Response intercept(Chain chain) throws IOException {
			Request request = chain.request();
			Request.Builder builder = request.newBuilder();
			builder.addHeader("Accept", "application/json;versions=1");
			if (isNetworkConnected(context)) {
				int maxAge = 60;
				builder.addHeader("Cache-Control", "public, max-age=" + maxAge);
			} else {
				int maxStale = 60 * 60 * 24 * 28;
				builder.addHeader("Cache-Control", "public, only-if-cached, max-stale=" + maxStale);
			}
			// 可添加token
//            if (listener != null) {
//                builder.addHeader("token", listener.getToken());
//            }
			// 如有需要，添加请求头
//            builder.addHeader("a", HttpHead.getHeader(request.method()));
			return chain.proceed(builder.build());
		}
	}

	private HttpLoggingInterceptor getInterceptor() {
		HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor();
		if (debug) {
			interceptor.setLevel(HttpLoggingInterceptor.Level.BODY); // 测试
		} else {
			interceptor.setLevel(HttpLoggingInterceptor.Level.NONE); // 打包
		}
		return interceptor;
	}

	/**
	 * 判断网络是否连通
	 */
	private boolean isNetworkConnected(Context context) {
		try {
			if (context == null) {
				/**如果context为空，就返回false，表示网络未连接*/
				return false;
			} else {
				ConnectivityManager cm = (ConnectivityManager) context
						.getSystemService(context.CONNECTIVITY_SERVICE);
				NetworkInfo info = cm.getActiveNetworkInfo();
				return info != null && info.isConnected();
			}
		} catch (Exception e) {
			e.printStackTrace();
			return false;
		}


	}
}
